package validation

import (
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"inspector/pkg/code"
	"inspector/pkg/errors"
)

type FieldError struct {
	Field       string      `json:"field"`
	Tag         string      `json:"tag"`
	ActualValue interface{} `json:"actualValue,omitempty"`
	Namespace   string      `json:"namespace,omitempty"`
}

func ValidateAll[T RequestValidator](c *gin.Context, req T) *errors.Error {
	if err := c.ShouldBind(&req); err != nil {
		var validationErrors validator.ValidationErrors
		if errors.As(err, &validationErrors) {
			var fieldErrors []FieldError
			for _, ve := range validationErrors {
				fieldErrors = append(fieldErrors, FieldError{
					Field: ve.Field(),
					Tag:   ve.Tag(),
				})
			}
			return errors.New(code.NewErrValidation().WithDetail("errors", fieldErrors), "validation failed")
		} else {
			return errors.New(code.NewErrBadRequest(), "failed to bind request data")
		}
	}
	return req.Validate()
}

//func ValidateByPriority[T any](c *gin.Context, req *T) *ValidateErrors {
//	if err := c.ShouldBind(req); err != nil {
//		validationErrors, ok := err.(validator.ValidationErrors)
//		if !ok {
//			return &ValidateErrors{
//				Errors: []code.ErrorCode{code.ErrBindingFailed.WithDetail("Failed to bind request data")},
//			}
//		}
//
//		ve := validationErrors[0]
//		errMsg := fmt.Sprintf("%s failed validation: %s", ve.Field(), ve.Tag())
//		return &ValidateErrors{
//			Errors: []code.ErrorCode{errors.ErrValidationFailed.WithDetail(errMsg)},
//		}
//	}
//	return nil
//}

type DefaultValidator struct {
}

func (dv DefaultValidator) Validate() *errors.Error {
	return nil
}

type RequestValidator interface {
	Validate() *errors.Error
}
